package server

import (
	"context"
	"errors"
	"fmt"
	"go.uber.org/zap"
	"google.golang.org/grpc"
	"io"
	"lht-go-plugins/LhtLog"
	"lht-go-plugins/LhtSettings"
	pb "lht-go-plugins/internal/server/proto"
	"net"
	"strconv"
	"sync"
)

type PluginHandler func(req *pb.CommonRequest) (*pb.CommonResponse, error)
type AsyncPluginHandler func(stream pb.PluginService_HandleRequestStreamServer, req *pb.CommonRequest)

// PluginServiceImpl 统一插件服务实现
type PluginServiceImpl struct {
	pb.UnimplementedPluginServiceServer
	asyncTasks    map[string]chan *pb.CommonResponse
	asyncTaskMux  sync.RWMutex
	syncHandlers  map[pb.PluginType]PluginHandler
	asyncHandlers map[pb.PluginType]AsyncPluginHandler
}

// NewPluginServiceImpl 创建服务实例
func NewPluginServiceImpl(cfg any) error {
	conf, ok := cfg.(*LhtSettings.AppConfig)
	if !ok {
		return errors.New("invalid config type: expected *AppConfig")
	}
	if conf == nil {
		return errors.New("AppConfig config missing")
	}

	s := &PluginServiceImpl{
		asyncTasks:    make(map[string]chan *pb.CommonResponse),
		syncHandlers:  make(map[pb.PluginType]PluginHandler),
		asyncHandlers: make(map[pb.PluginType]AsyncPluginHandler),
	}
	// 注册不同类型插件的处理逻辑
	// 注册同步处理方法
	s.syncHandlers[pb.PluginType_GEO] = s.handleGeoSync
	s.syncHandlers[pb.PluginType_ALGORITHM] = s.handleAlgorithmSync
	s.syncHandlers[pb.PluginType_ENCRYPTION] = s.handleEncryptSync
	s.syncHandlers[pb.PluginType_CACHE] = s.handleCacheSync
	s.syncHandlers[pb.PluginType_DATABASE] = s.handleDatabaseSync

	// 注册异步处理方法
	s.asyncHandlers[pb.PluginType_GEO] = s.handleGeoAsync
	s.asyncHandlers[pb.PluginType_ALGORITHM] = s.handleAlgorithmAsync
	s.asyncHandlers[pb.PluginType_ENCRYPTION] = s.handleEncryptAsync
	s.asyncHandlers[pb.PluginType_CACHE] = s.handleCacheAsync
	s.asyncHandlers[pb.PluginType_DATABASE] = s.handleDatabaseAsync

	port := strconv.Itoa(conf.GrpcPort)
	lis, err := net.Listen("tcp", ":"+port)
	if err != nil {
		return errors.New("监听失败:" + err.Error())
	}
	grpcServer := grpc.NewServer()
	pb.RegisterPluginServiceServer(grpcServer, s)
	LhtLog.Info("gRPC", zap.String("插件服务已启动，监听端口", port))
	go grpcServer.Serve(lis)
	return nil
}

// -------------------- 同步请求 --------------------
func (s *PluginServiceImpl) HandleRequestSync(ctx context.Context, req *pb.CommonRequest) (*pb.CommonResponse, error) {
	fmt.Printf("[SYNC] 请求ID: %s, 插件类型: %v, 方法: %s\n", req.RequestId, req.PluginType, req.Method)

	handler, ok := s.syncHandlers[req.PluginType]
	if !ok {
		return &pb.CommonResponse{
			RequestId: req.RequestId,
			Code:      404,
			Message:   fmt.Sprintf("未知的插件类型: %v", req.PluginType),
		}, nil
	}

	return handler(req)
}

// 双向流异步处理
func (s *PluginServiceImpl) HandleRequestStream(stream pb.PluginService_HandleRequestStreamServer) error {
	fmt.Println("[STREAM] 开始处理双向流连接")

	for {
		req, err := stream.Recv()
		if err == io.EOF {
			fmt.Println("[STREAM] 客户端关闭连接")
			return nil
		}
		if err != nil {
			fmt.Printf("[STREAM] 接收错误: %v\n", err)
			return err
		}

		fmt.Printf("[STREAM] 收到异步任务请求: %s\n", req.RequestId)

		handler, ok := s.asyncHandlers[req.PluginType]
		if !ok {
			resp := &pb.CommonResponse{
				RequestId: req.RequestId,
				Code:      404,
				Message:   "未知的插件类型（异步）",
			}
			_ = stream.Send(resp)
			continue
		}

		// 开启异步任务
		go handler(stream, req)
	}
}
